{
 "metadata": {
  "kernelspec": {
   "language": "python",
   "display_name": "Python 3",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.8.16",
   "mimetype": "text/x-python",
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "pygments_lexer": "ipython3",
   "nbconvert_exporter": "python",
   "file_extension": ".py"
  },
  "kaggle": {
   "accelerator": "tpu1vmV38",
   "dataSources": [
    {
     "sourceId": 34377,
     "databundleVersionId": 3220602,
     "sourceType": "competition"
    }
   ],
   "dockerImageVersionId": 30407,
   "isInternetEnabled": true,
   "language": "python",
   "sourceType": "notebook",
   "isGpuEnabled": false
  }
 },
 "nbformat_minor": 4,
 "nbformat": 4,
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# Spaceship Titanic Dataset with TensorFlow Decision Forests"
   ],
   "metadata": {
    "id": "Ck00s7mTmnjA"
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "This notebook walks you through how to train a baseline Random Forest model using TensorFlow Decision Forests on the Spaceship Titanic dataset made available for this competition.\n",
    "\n",
    "Roughly, the code will look as follows:\n",
    "\n",
    "```\n",
    "import tensorflow_decision_forests as tfdf\n",
    "import pandas as pd\n",
    "\n",
    "dataset = pd.read_csv(\"project/dataset.csv\")\n",
    "tf_dataset = tfdf.keras.pd_dataframe_to_tf_dataset(dataset, label=\"my_label\")\n",
    "\n",
    "model = tfdf.keras.RandomForestModel()\n",
    "model.fit(tf_dataset)\n",
    "\n",
    "print(model.summary())\n",
    "```\n",
    "\n",
    "Decision Forests are a family of tree-based models including Random Forests and Gradient Boosted Trees. They are the best place to start when working with tabular data, and will often outperform (or provide a strong baseline) before you begin experimenting with neural networks."
   ],
   "metadata": {
    "id": "62leGXylmnjF"
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Import the library"
   ],
   "metadata": {
    "id": "UPNzfVOEmnjH"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "import tensorflow as tf\n",
    "import tensorflow_decision_forests as tfdf\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt"
   ],
   "metadata": {
    "id": "mmwBzpblmnjH",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:12:59.221283Z",
     "iopub.execute_input": "2024-02-19T07:12:59.221541Z",
     "iopub.status.idle": "2024-02-19T07:13:18.142312Z",
     "shell.execute_reply.started": "2024-02-19T07:12:59.221515Z",
     "shell.execute_reply": "2024-02-19T07:13:18.139723Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "end_time": "2024-02-20T07:18:53.371623Z",
     "start_time": "2024-02-20T07:18:35.816906Z"
    }
   },
   "execution_count": 1,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From C:\\Users\\igorl\\AppData\\Roaming\\Python\\Python311\\site-packages\\keras\\src\\losses.py:2976: The name tf.losses.sparse_softmax_cross_entropy is deprecated. Please use tf.compat.v1.losses.sparse_softmax_cross_entropy instead.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:root:Failure to load the inference.so custom c++ tensorflow ops. This error is likely caused the version of TensorFlow and TensorFlow Decision Forests are not compatible. Full error:C:\\Users\\igorl\\AppData\\Roaming\\Python\\Python311\\site-packages\\tensorflow_decision_forests\\tensorflow\\ops\\inference\\inference.so not found\n"
     ]
    },
    {
     "ename": "NotFoundError",
     "evalue": "C:\\Users\\igorl\\AppData\\Roaming\\Python\\Python311\\site-packages\\tensorflow_decision_forests\\tensorflow\\ops\\inference\\inference.so not found",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mNotFoundError\u001B[0m                             Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[1], line 2\u001B[0m\n\u001B[0;32m      1\u001B[0m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01mtensorflow\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m \u001B[38;5;21;01mtf\u001B[39;00m\n\u001B[1;32m----> 2\u001B[0m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m \u001B[38;5;21;01mtfdf\u001B[39;00m\n\u001B[0;32m      3\u001B[0m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01mpandas\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m \u001B[38;5;21;01mpd\u001B[39;00m\n\u001B[0;32m      4\u001B[0m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01mnumpy\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m \u001B[38;5;21;01mnp\u001B[39;00m\n",
      "File \u001B[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\tensorflow_decision_forests\\__init__.py:64\u001B[0m\n\u001B[0;32m     60\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mtensorflow\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m check_version\n\u001B[0;32m     62\u001B[0m check_version\u001B[38;5;241m.\u001B[39mcheck_version(__version__, compatible_tf_versions)\n\u001B[1;32m---> 64\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m keras\n\u001B[0;32m     65\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mcomponent\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m py_tree\n\u001B[0;32m     66\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mcomponent\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mbuilder\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m builder\n",
      "File \u001B[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\tensorflow_decision_forests\\keras\\__init__.py:53\u001B[0m\n\u001B[0;32m     15\u001B[0m \u001B[38;5;124;03m\"\"\"Decision Forest in a Keras Model.\u001B[39;00m\n\u001B[0;32m     16\u001B[0m \n\u001B[0;32m     17\u001B[0m \u001B[38;5;124;03mUsage example:\u001B[39;00m\n\u001B[1;32m   (...)\u001B[0m\n\u001B[0;32m     48\u001B[0m \u001B[38;5;124;03m```\u001B[39;00m\n\u001B[0;32m     49\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[0;32m     51\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtyping\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m Callable, List\n\u001B[1;32m---> 53\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mkeras\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m core\n\u001B[0;32m     54\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mkeras\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m wrappers\n\u001B[0;32m     56\u001B[0m \u001B[38;5;66;03m# Utility classes\u001B[39;00m\n",
      "File \u001B[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\tensorflow_decision_forests\\keras\\core.py:62\u001B[0m\n\u001B[0;32m     60\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mcomponent\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01minspector\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m inspector \u001B[38;5;28;01mas\u001B[39;00m inspector_lib\n\u001B[0;32m     61\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mcomponent\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mtuner\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m tuner \u001B[38;5;28;01mas\u001B[39;00m tuner_lib\n\u001B[1;32m---> 62\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mkeras\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m core_inference\n\u001B[0;32m     63\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mtensorflow\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m cc_logging\n\u001B[0;32m     64\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mtensorflow\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m core \u001B[38;5;28;01mas\u001B[39;00m tf_core\n",
      "File \u001B[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\tensorflow_decision_forests\\keras\\core_inference.py:36\u001B[0m\n\u001B[0;32m     34\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mtensorflow\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m core_inference \u001B[38;5;28;01mas\u001B[39;00m tf_core\n\u001B[0;32m     35\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mtensorflow\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m tf_logging\n\u001B[1;32m---> 36\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mtensorflow\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mops\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01minference\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m api \u001B[38;5;28;01mas\u001B[39;00m tf_op\n\u001B[0;32m     37\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01myggdrasil_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mlearner\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m abstract_learner_pb2\n\u001B[0;32m     38\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01myggdrasil_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mlearner\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mmultitasker\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m multitasker_pb2\n",
      "File \u001B[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\tensorflow_decision_forests\\tensorflow\\ops\\inference\\api.py:179\u001B[0m\n\u001B[0;32m    177\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mcomponent\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01minspector\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m inspector \u001B[38;5;28;01mas\u001B[39;00m inspector_lib\n\u001B[0;32m    178\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mtensorflow\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m tf1_compatibility\n\u001B[1;32m--> 179\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mtensorflow\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mops\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01minference\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m op\n\u001B[0;32m    180\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01myggdrasil_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mdataset\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m data_spec_pb2\n\u001B[0;32m    181\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01myggdrasil_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mmodel\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m abstract_model_pb2\n",
      "File \u001B[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\tensorflow_decision_forests\\tensorflow\\ops\\inference\\op.py:15\u001B[0m\n\u001B[0;32m      1\u001B[0m \u001B[38;5;66;03m# Copyright 2021 Google LLC.\u001B[39;00m\n\u001B[0;32m      2\u001B[0m \u001B[38;5;66;03m#\u001B[39;00m\n\u001B[0;32m      3\u001B[0m \u001B[38;5;66;03m# Licensed under the Apache License, Version 2.0 (the \"License\");\u001B[39;00m\n\u001B[1;32m   (...)\u001B[0m\n\u001B[0;32m     12\u001B[0m \u001B[38;5;66;03m# See the License for the specific language governing permissions and\u001B[39;00m\n\u001B[0;32m     13\u001B[0m \u001B[38;5;66;03m# limitations under the License.\u001B[39;00m\n\u001B[1;32m---> 15\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mtensorflow_decision_forests\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mtensorflow\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mops\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01minference\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mop_dynamic\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;241m*\u001B[39m\n",
      "File \u001B[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\tensorflow_decision_forests\\tensorflow\\ops\\inference\\op_dynamic.py:24\u001B[0m\n\u001B[0;32m     22\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[0;32m     23\u001B[0m   check_version\u001B[38;5;241m.\u001B[39minfo_fail_to_load_custom_op(e, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124minference.so\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m---> 24\u001B[0m   \u001B[38;5;28;01mraise\u001B[39;00m e\n\u001B[0;32m     26\u001B[0m \u001B[38;5;66;03m# Importing all the symbols.\u001B[39;00m\n\u001B[0;32m     27\u001B[0m module \u001B[38;5;241m=\u001B[39m sys\u001B[38;5;241m.\u001B[39mmodules[\u001B[38;5;18m__name__\u001B[39m]\n",
      "File \u001B[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\tensorflow_decision_forests\\tensorflow\\ops\\inference\\op_dynamic.py:21\u001B[0m\n\u001B[0;32m     18\u001B[0m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01msys\u001B[39;00m\n\u001B[0;32m     20\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m---> 21\u001B[0m   ops \u001B[38;5;241m=\u001B[39m tf\u001B[38;5;241m.\u001B[39mload_op_library(resource_loader\u001B[38;5;241m.\u001B[39mget_path_to_datafile(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124minference.so\u001B[39m\u001B[38;5;124m\"\u001B[39m))\n\u001B[0;32m     22\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[0;32m     23\u001B[0m   check_version\u001B[38;5;241m.\u001B[39minfo_fail_to_load_custom_op(e, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124minference.so\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n",
      "File \u001B[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\tensorflow\\python\\framework\\load_library.py:54\u001B[0m, in \u001B[0;36mload_op_library\u001B[1;34m(library_filename)\u001B[0m\n\u001B[0;32m     31\u001B[0m \u001B[38;5;129m@tf_export\u001B[39m(\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mload_op_library\u001B[39m\u001B[38;5;124m'\u001B[39m)\n\u001B[0;32m     32\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mload_op_library\u001B[39m(library_filename):\n\u001B[0;32m     33\u001B[0m \u001B[38;5;250m  \u001B[39m\u001B[38;5;124;03m\"\"\"Loads a TensorFlow plugin, containing custom ops and kernels.\u001B[39;00m\n\u001B[0;32m     34\u001B[0m \n\u001B[0;32m     35\u001B[0m \u001B[38;5;124;03m  Pass \"library_filename\" to a platform-specific mechanism for dynamically\u001B[39;00m\n\u001B[1;32m   (...)\u001B[0m\n\u001B[0;32m     52\u001B[0m \u001B[38;5;124;03m    RuntimeError: when unable to load the library or get the python wrappers.\u001B[39;00m\n\u001B[0;32m     53\u001B[0m \u001B[38;5;124;03m  \"\"\"\u001B[39;00m\n\u001B[1;32m---> 54\u001B[0m   lib_handle \u001B[38;5;241m=\u001B[39m py_tf\u001B[38;5;241m.\u001B[39mTF_LoadLibrary(library_filename)\n\u001B[0;32m     55\u001B[0m   \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m     56\u001B[0m     wrappers \u001B[38;5;241m=\u001B[39m _pywrap_python_op_gen\u001B[38;5;241m.\u001B[39mGetPythonWrappers(\n\u001B[0;32m     57\u001B[0m         py_tf\u001B[38;5;241m.\u001B[39mTF_GetOpList(lib_handle))\n",
      "\u001B[1;31mNotFoundError\u001B[0m: C:\\Users\\igorl\\AppData\\Roaming\\Python\\Python311\\site-packages\\tensorflow_decision_forests\\tensorflow\\ops\\inference\\inference.so not found"
     ]
    }
   ]
  },
  {
   "cell_type": "code",
   "source": [
    "print(\"TensorFlow v\" + tf.__version__)\n",
    "print(\"TensorFlow Decision Forests v\" + tfdf.__version__)"
   ],
   "metadata": {
    "id": "grAO86gTmnjJ",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.142998Z",
     "iopub.status.idle": "2024-02-19T07:13:18.143327Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.143159Z",
     "shell.execute_reply": "2024-02-19T07:13:18.143177Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "end_time": "2024-02-19T08:10:25.778254Z",
     "start_time": "2024-02-19T08:10:25.747518Z"
    }
   },
   "execution_count": 3,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TensorFlow v2.15.0\n"
     ]
    },
    {
     "ename": "NameError",
     "evalue": "name 'tfdf' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mNameError\u001B[0m                                 Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[3], line 2\u001B[0m\n\u001B[0;32m      1\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mTensorFlow v\u001B[39m\u001B[38;5;124m\"\u001B[39m \u001B[38;5;241m+\u001B[39m tf\u001B[38;5;241m.\u001B[39m__version__)\n\u001B[1;32m----> 2\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mTensorFlow Decision Forests v\u001B[39m\u001B[38;5;124m\"\u001B[39m \u001B[38;5;241m+\u001B[39m tfdf\u001B[38;5;241m.\u001B[39m__version__)\n",
      "\u001B[1;31mNameError\u001B[0m: name 'tfdf' is not defined"
     ]
    }
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Load the Dataset"
   ],
   "metadata": {
    "id": "6sHFpppPmnjJ"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "# Load a dataset into a Pandas Dataframe\n",
    "dataset_df = pd.read_csv('/kaggle/input/spaceship-titanic/train.csv')\n",
    "print(\"Full train dataset shape is {}\".format(dataset_df.shape))"
   ],
   "metadata": {
    "id": "c1P3Y3a7mnjL",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.144180Z",
     "iopub.status.idle": "2024-02-19T07:13:18.144476Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.144326Z",
     "shell.execute_reply": "2024-02-19T07:13:18.144342Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "end_time": "2024-02-19T07:14:13.023848Z",
     "start_time": "2024-02-19T07:14:13.022531Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "The data is composed of 14 columns and 8693 entries. We can see all 14 dimensions of our dataset by printing out the first 5 entries using the following code:"
   ],
   "metadata": {
    "id": "cEd92zhJmnjL"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "# Display the first 5 examples\n",
    "dataset_df.head(5)"
   ],
   "metadata": {
    "id": "nCx3PE1xmnjM",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.145472Z",
     "iopub.status.idle": "2024-02-19T07:13:18.145775Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.145613Z",
     "shell.execute_reply": "2024-02-19T07:13:18.145627Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "end_time": "2024-02-19T07:14:13.027683Z",
     "start_time": "2024-02-19T07:14:13.026147Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "There are 12 feature columns. Using these features your model has to predict whether the passenger is rescued or not indicated by the column `Transported`."
   ],
   "metadata": {
    "id": "0-Euaq6dmnjN"
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Let us quickly do a basic exploration of the dataset"
   ],
   "metadata": {
    "id": "1-Ewr6XDmnjN"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "dataset_df.describe()"
   ],
   "metadata": {
    "id": "XjwG5wjfmnjO",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.146500Z",
     "iopub.status.idle": "2024-02-19T07:13:18.146797Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.146638Z",
     "shell.execute_reply": "2024-02-19T07:13:18.146653Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "end_time": "2024-02-19T07:14:13.033566Z",
     "start_time": "2024-02-19T07:14:13.032440Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "code",
   "source": [
    "dataset_df.info()"
   ],
   "metadata": {
    "id": "UmWpnVxQmnjO",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.148110Z",
     "iopub.status.idle": "2024-02-19T07:13:18.148390Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.148250Z",
     "shell.execute_reply": "2024-02-19T07:13:18.148265Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "end_time": "2024-02-19T07:14:13.036839Z",
     "start_time": "2024-02-19T07:14:13.034681Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Bar chart for label column: Transported\n",
    "\n"
   ],
   "metadata": {
    "id": "PYbIPVaCmnjO"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "plot_df = dataset_df.Transported.value_counts()\n",
    "plot_df.plot(kind=\"bar\")"
   ],
   "metadata": {
    "id": "DcaGweARmnjP",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.149180Z",
     "iopub.status.idle": "2024-02-19T07:13:18.149453Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.149315Z",
     "shell.execute_reply": "2024-02-19T07:13:18.149330Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "end_time": "2024-02-19T07:14:13.039274Z",
     "start_time": "2024-02-19T07:14:13.039274Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Numerical data distribution\n",
    "\n",
    "Let us plot all the numerical columns and their value counts:"
   ],
   "metadata": {
    "id": "LRO2hJlNmnjP"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "fig, ax = plt.subplots(5,1,  figsize=(10, 10))\n",
    "plt.subplots_adjust(top = 2)\n",
    "\n",
    "sns.histplot(dataset_df['Age'], color='b', bins=50, ax=ax[0]);\n",
    "sns.histplot(dataset_df['FoodCourt'], color='b', bins=50, ax=ax[1]);\n",
    "sns.histplot(dataset_df['ShoppingMall'], color='b', bins=50, ax=ax[2]);\n",
    "sns.histplot(dataset_df['Spa'], color='b', bins=50, ax=ax[3]);\n",
    "sns.histplot(dataset_df['VRDeck'], color='b', bins=50, ax=ax[4]);"
   ],
   "metadata": {
    "id": "lafxj4fkmnjQ",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.150243Z",
     "iopub.status.idle": "2024-02-19T07:13:18.150520Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.150381Z",
     "shell.execute_reply": "2024-02-19T07:13:18.150396Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "end_time": "2024-02-19T07:14:13.044745Z",
     "start_time": "2024-02-19T07:14:13.042561Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Prepare the dataset"
   ],
   "metadata": {
    "id": "Trlsxv1emnjQ"
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "We will drop both `PassengerId` and `Name` columns as they are not necessary for model training."
   ],
   "metadata": {
    "id": "c-BLN1jcmnjQ"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "dataset_df = dataset_df.drop(['PassengerId', 'Name'], axis=1)\n",
    "dataset_df.head(5)"
   ],
   "metadata": {
    "id": "nftfBG67mnjR",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.151871Z",
     "iopub.status.idle": "2024-02-19T07:13:18.152210Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.152041Z",
     "shell.execute_reply": "2024-02-19T07:13:18.152059Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "end_time": "2024-02-19T07:14:13.049870Z",
     "start_time": "2024-02-19T07:14:13.046884Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "We will check for the missing values using the following code:"
   ],
   "metadata": {
    "id": "pXhbIKCemnjR"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "dataset_df.isnull().sum().sort_values(ascending=False)"
   ],
   "metadata": {
    "id": "3_VMZ9a1mnjR",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.153128Z",
     "iopub.status.idle": "2024-02-19T07:13:18.153448Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.153284Z",
     "shell.execute_reply": "2024-02-19T07:13:18.153301Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "end_time": "2024-02-19T07:14:13.053390Z",
     "start_time": "2024-02-19T07:14:13.052311Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "This dataset contains a mix of numeric, categorical and missing features. TF-DF supports all these feature types natively, and no preprocessing is required.\n",
    "\n",
    "But this datatset also has boolean fields with missing values. TF-DF doesn't support boolean fields yet. So we need to convert those fields into int. To account for the missing values in the boolean fields, we will replace them with zero.\n",
    "\n",
    "In this notebook, we will replace null value entries with zero for numerical columns as well and only let TF-DF handle the missing values in categorical columns.\n",
    "\n",
    "Note: You can choose to let TF-DF handle missing values in numerical columns if need be."
   ],
   "metadata": {
    "id": "vlWOQl4fmnjS"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "dataset_df[['VIP', 'CryoSleep', 'FoodCourt', 'ShoppingMall', 'Spa', 'VRDeck']] = dataset_df[['VIP', 'CryoSleep', 'FoodCourt', 'ShoppingMall', 'Spa', 'VRDeck']].fillna(value=0)\n",
    "dataset_df.isnull().sum().sort_values(ascending=False)"
   ],
   "metadata": {
    "id": "ASQ5Bh2JmnjS",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.154152Z",
     "iopub.status.idle": "2024-02-19T07:13:18.154528Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.154294Z",
     "shell.execute_reply": "2024-02-19T07:13:18.154308Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "start_time": "2024-02-19T07:14:13.055568Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "Since, TF-DF cannot handle boolean columns, we will have to adjust the labels in column `Transported` to convert them into the integer format that TF-DF expects."
   ],
   "metadata": {
    "id": "tFbE6D0BmnjT"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "label = \"Transported\"\n",
    "dataset_df[label] = dataset_df[label].astype(int)"
   ],
   "metadata": {
    "id": "-T6a_RTxmnjT",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.155261Z",
     "iopub.status.idle": "2024-02-19T07:13:18.155536Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.155398Z",
     "shell.execute_reply": "2024-02-19T07:13:18.155413Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "end_time": "2024-02-19T07:14:13.057731Z",
     "start_time": "2024-02-19T07:14:13.057731Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "We will also convert the boolean fields `CryoSleep` and `VIP` to int."
   ],
   "metadata": {
    "id": "F6-GATuzmnjU"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "dataset_df['VIP'] = dataset_df['VIP'].astype(int)\n",
    "dataset_df['CryoSleep'] = dataset_df['CryoSleep'].astype(int)"
   ],
   "metadata": {
    "id": "Wq6PbMnnmnjU",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.156377Z",
     "iopub.status.idle": "2024-02-19T07:13:18.156651Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.156513Z",
     "shell.execute_reply": "2024-02-19T07:13:18.156528Z"
    },
    "trusted": true
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "The value of column `Cabin` is a string with the format `Deck/Cabin_num/Side`. Here we will split the `Cabin` column and create 3 new columns `Deck`, `Cabin_num` and `Side`, since it will be easier to train the model on those individual data.\n",
    "\n",
    "Run the following command to split the column `Cabin` into columns `Deck`, `Cabin_num` and `Side`"
   ],
   "metadata": {
    "id": "enjp51h_mnjV"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "dataset_df[[\"Deck\", \"Cabin_num\", \"Side\"]] = dataset_df[\"Cabin\"].str.split(\"/\", expand=True)"
   ],
   "metadata": {
    "id": "JeAuUvb_mnjV",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.157808Z",
     "iopub.status.idle": "2024-02-19T07:13:18.158099Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.157952Z",
     "shell.execute_reply": "2024-02-19T07:13:18.157967Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "start_time": "2024-02-19T07:14:13.067692Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "Remove original `Cabin` column from the dataset since it's not needed anymore."
   ],
   "metadata": {
    "id": "vNYEd1AkmnjV"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "try:\n",
    "    dataset_df = dataset_df.drop('Cabin', axis=1)\n",
    "except KeyError:\n",
    "    print(\"Field does not exist\")"
   ],
   "metadata": {
    "id": "dOcny3s4mnjV",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.158851Z",
     "iopub.status.idle": "2024-02-19T07:13:18.159134Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.158994Z",
     "shell.execute_reply": "2024-02-19T07:13:18.159008Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "start_time": "2024-02-19T07:14:13.071004Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "Let us display the first 5 examples from the prepared dataset."
   ],
   "metadata": {
    "id": "Y7byxj5FmnjW"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "dataset_df.head(5)"
   ],
   "metadata": {
    "id": "g0U1OKAYmnjW",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.159942Z",
     "iopub.status.idle": "2024-02-19T07:13:18.160229Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.160089Z",
     "shell.execute_reply": "2024-02-19T07:13:18.160104Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "start_time": "2024-02-19T07:14:13.074237Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "Now let us split the dataset into training and testing datasets:"
   ],
   "metadata": {
    "id": "l6EmJsSfmnjW"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "def split_dataset(dataset, test_ratio=0.20):\n",
    "  test_indices = np.random.rand(len(dataset)) < test_ratio\n",
    "  return dataset[~test_indices], dataset[test_indices]\n",
    "\n",
    "train_ds_pd, valid_ds_pd = split_dataset(dataset_df)\n",
    "print(\"{} examples in training, {} examples in testing.\".format(\n",
    "    len(train_ds_pd), len(valid_ds_pd)))"
   ],
   "metadata": {
    "id": "_drMgwAAmnjX",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.161241Z",
     "iopub.status.idle": "2024-02-19T07:13:18.161557Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.161380Z",
     "shell.execute_reply": "2024-02-19T07:13:18.161395Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "start_time": "2024-02-19T07:14:13.077512Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "There's one more step required before we can train the model. We need to convert the datatset from Pandas format (`pd.DataFrame`) into TensorFlow Datasets format (`tf.data.Dataset`).\n",
    "\n",
    "[TensorFlow Datasets](https://www.tensorflow.org/datasets/overview) is a high performance data loading library which is helpful when training neural networks with accelerators like GPUs and TPUs."
   ],
   "metadata": {
    "id": "_gg4nfB1mnjX"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "train_ds = tfdf.keras.pd_dataframe_to_tf_dataset(train_ds_pd, label=label)\n",
    "valid_ds = tfdf.keras.pd_dataframe_to_tf_dataset(valid_ds_pd, label=label)"
   ],
   "metadata": {
    "id": "LZADOplXmnjX",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.162561Z",
     "iopub.status.idle": "2024-02-19T07:13:18.163023Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.162839Z",
     "shell.execute_reply": "2024-02-19T07:13:18.162858Z"
    },
    "trusted": true
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Select a Model\n",
    "\n",
    "There are several tree-based models for you to choose from.\n",
    "\n",
    "* RandomForestModel\n",
    "* GradientBoostedTreesModel\n",
    "* CartModel\n",
    "* DistributedGradientBoostedTreesModel\n",
    "\n",
    "To start, we'll work with a Random Forest. This is the most well-known of the Decision Forest training algorithms.\n",
    "\n",
    "A Random Forest is a collection of decision trees, each trained independently on a random subset of the training dataset (sampled with replacement). The algorithm is unique in that it is robust to overfitting, and easy to use.\n",
    "\n",
    "We can list the all the available models in TensorFlow Decision Forests using the following code:"
   ],
   "metadata": {
    "id": "0-xUiOTwmnjY"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "tfdf.keras.get_all_models()"
   ],
   "metadata": {
    "id": "PdQw1cWbmnjY",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.164029Z",
     "iopub.status.idle": "2024-02-19T07:13:18.164313Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.164169Z",
     "shell.execute_reply": "2024-02-19T07:13:18.164184Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "start_time": "2024-02-19T07:14:13.089421Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Configure the model\n",
    "\n",
    "TensorFlow Decision Forests provides good defaults for you (e.g. the top ranking hyperparameters on our benchmarks, slightly modified to run in reasonable time). If you would like to configure the learning algorithm, you will find many options you can explore to get the highest possible accuracy.\n",
    "\n",
    "You can select a template and/or set parameters as follows:\n",
    "\n",
    "```rf = tfdf.keras.RandomForestModel(hyperparameter_template=\"benchmark_rank1\")```\n",
    "\n",
    "Read more [here](https://www.tensorflow.org/decision_forests/api_docs/python/tfdf/keras/RandomForestModel)."
   ],
   "metadata": {
    "id": "sy81fpfxmnjY"
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Create a Random Forest\n",
    "\n",
    "Today, we will use the defaults to create the Random Forest Model. By default the model is set to train for a classification task."
   ],
   "metadata": {
    "id": "AfJMCA6lmnjZ"
   }
  },
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "source": [
    "rf = tfdf.keras.RandomForestModel()\n",
    "rf.compile(metrics=[\"accuracy\"]) # Optional, you can use this to include a list of eval metrics"
   ],
   "metadata": {
    "id": "j7-gFVDNmnjZ",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.165315Z",
     "iopub.status.idle": "2024-02-19T07:13:18.165592Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.165450Z",
     "shell.execute_reply": "2024-02-19T07:13:18.165465Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "start_time": "2024-02-19T07:14:13.092948Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Train the model\n",
    "\n",
    "We will train the model using a one-liner.\n",
    "\n",
    "Note: you may see a warning about Autograph. You can safely ignore this, it will be fixed in the next release."
   ],
   "metadata": {
    "id": "wEQXtv4MmnjZ"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "rf.fit(x=train_ds)"
   ],
   "metadata": {
    "id": "QcL5KRyLmnja",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.166643Z",
     "iopub.status.idle": "2024-02-19T07:13:18.166948Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.166798Z",
     "shell.execute_reply": "2024-02-19T07:13:18.166813Z"
    },
    "trusted": true
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Visualize the model\n",
    "One benefit of tree-based models is that we can easily visualize them. The default number of trees used in the Random Forests is 300. We can select a tree to display below."
   ],
   "metadata": {
    "id": "HQaPDLBjmnja"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "tfdf.model_plotter.plot_model_in_colab(rf, tree_idx=0, max_depth=3)"
   ],
   "metadata": {
    "id": "hSao4Qstmnja",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.167847Z",
     "iopub.status.idle": "2024-02-19T07:13:18.168133Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.167991Z",
     "shell.execute_reply": "2024-02-19T07:13:18.168006Z"
    },
    "trusted": true
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Evaluate the model on the Out of bag (OOB) data and the validation dataset\n",
    "\n",
    "Before training the dataset we have manually seperated 20% of the dataset for validation named as `valid_ds`.\n",
    "\n",
    "We can also use Out of bag (OOB) score to validate our RandomForestModel.\n",
    "To train a Random Forest Model, a set of random samples from training set are choosen by the algorithm and the rest of the samples are used to finetune the model.The subset of data that is not chosen is known as Out of bag data (OOB).\n",
    "OOB score is computed on the OOB data.\n",
    "\n",
    "Read more about OOB data [here](https://developers.google.com/machine-learning/decision-forests/out-of-bag).\n",
    "\n",
    "The training logs show the accuracy evaluated on the out-of-bag dataset according to the number of trees in the model. Let us plot this.\n",
    "\n",
    "Note: Larger values are better for this hyperparameter."
   ],
   "metadata": {
    "id": "1q5zxzuLmnjb"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "import matplotlib.pyplot as plt\n",
    "logs = rf.make_inspector().training_logs()\n",
    "plt.plot([log.num_trees for log in logs], [log.evaluation.accuracy for log in logs])\n",
    "plt.xlabel(\"Number of trees\")\n",
    "plt.ylabel(\"Accuracy (out-of-bag)\")\n",
    "plt.show()"
   ],
   "metadata": {
    "id": "z7u4IuAQmnjb",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.168898Z",
     "iopub.status.idle": "2024-02-19T07:13:18.169181Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.169040Z",
     "shell.execute_reply": "2024-02-19T07:13:18.169055Z"
    },
    "trusted": true
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "We can also see some general stats on the OOB dataset:"
   ],
   "metadata": {
    "id": "N24V7vhAmnjb"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "inspector = rf.make_inspector()\n",
    "inspector.evaluation()"
   ],
   "metadata": {
    "id": "QTD92zMGmnjc",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.170195Z",
     "iopub.status.idle": "2024-02-19T07:13:18.170472Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.170334Z",
     "shell.execute_reply": "2024-02-19T07:13:18.170348Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "start_time": "2024-02-19T07:14:13.110802Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "Now, let us run an evaluation using the validation dataset."
   ],
   "metadata": {
    "id": "SuVS0BGXmnjd"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "evaluation = rf.evaluate(x=valid_ds,return_dict=True)\n",
    "\n",
    "for name, value in evaluation.items():\n",
    "  print(f\"{name}: {value:.4f}\")"
   ],
   "metadata": {
    "id": "C0SfSxc0mnjd",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.171554Z",
     "iopub.status.idle": "2024-02-19T07:13:18.172036Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.171841Z",
     "shell.execute_reply": "2024-02-19T07:13:18.171873Z"
    },
    "trusted": true
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Variable importances\n",
    "\n",
    "Variable importances generally indicate how much a feature contributes to the model predictions or quality. There are several ways to identify important features using TensorFlow Decision Forests.\n",
    "Let us list the available `Variable Importances` for Decision Trees:"
   ],
   "metadata": {
    "id": "cgAI1XrVmnje"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "print(f\"Available variable importances:\")\n",
    "for importance in inspector.variable_importances().keys():\n",
    "  print(\"\\t\", importance)"
   ],
   "metadata": {
    "id": "BdPN_fV1mnje",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.172955Z",
     "iopub.status.idle": "2024-02-19T07:13:18.173287Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.173120Z",
     "shell.execute_reply": "2024-02-19T07:13:18.173138Z"
    },
    "trusted": true
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "As an example, let us display the important features for the Variable Importance `NUM_AS_ROOT`.\n",
    "\n",
    "The larger the importance score for `NUM_AS_ROOT`, the more impact it has on the outcome of the model.\n",
    "\n",
    "By default, the list is sorted from the most important to the least. From the output you can infer that the feature at the top of the list is used as the root node in most number of trees in the random forest than any other feature."
   ],
   "metadata": {
    "id": "dr-nVQwCmnje"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "# Each line is: (feature name, (index of the feature), importance score)\n",
    "inspector.variable_importances()[\"NUM_AS_ROOT\"]"
   ],
   "metadata": {
    "id": "etYOifhfmnje",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.174338Z",
     "iopub.status.idle": "2024-02-19T07:13:18.174625Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.174478Z",
     "shell.execute_reply": "2024-02-19T07:13:18.174492Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "start_time": "2024-02-19T07:14:13.118659Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Submission"
   ],
   "metadata": {
    "id": "DAtAR0vkmnje"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "# Load the test dataset\n",
    "test_df = pd.read_csv('/kaggle/input/spaceship-titanic/test.csv')\n",
    "submission_id = test_df.PassengerId\n",
    "\n",
    "# Replace NaN values with zero\n",
    "test_df[['VIP', 'CryoSleep']] = test_df[['VIP', 'CryoSleep']].fillna(value=0)\n",
    "\n",
    "# Creating New Features - Deck, Cabin_num and Side from the column Cabin and remove Cabin\n",
    "test_df[[\"Deck\", \"Cabin_num\", \"Side\"]] = test_df[\"Cabin\"].str.split(\"/\", expand=True)\n",
    "test_df = test_df.drop('Cabin', axis=1)\n",
    "\n",
    "# Convert boolean to 1's and 0's\n",
    "test_df['VIP'] = test_df['VIP'].astype(int)\n",
    "test_df['CryoSleep'] = test_df['CryoSleep'].astype(int)\n",
    "\n",
    "# Convert pd dataframe to tf dataset\n",
    "test_ds = tfdf.keras.pd_dataframe_to_tf_dataset(test_df)\n",
    "\n",
    "# Get the predictions for testdata\n",
    "predictions = rf.predict(test_ds)\n",
    "n_predictions = (predictions > 0.5).astype(bool)\n",
    "output = pd.DataFrame({'PassengerId': submission_id,\n",
    "                       'Transported': n_predictions.squeeze()})\n",
    "\n",
    "output.head()"
   ],
   "metadata": {
    "id": "KHBRzBD9mnjf",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.175818Z",
     "iopub.status.idle": "2024-02-19T07:13:18.176302Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.176039Z",
     "shell.execute_reply": "2024-02-19T07:13:18.176067Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "start_time": "2024-02-19T07:14:13.120841Z"
    }
   },
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "code",
   "source": [
    "sample_submission_df = pd.read_csv('/kaggle/input/spaceship-titanic/sample_submission.csv')\n",
    "sample_submission_df['Transported'] = n_predictions\n",
    "sample_submission_df.to_csv('/kaggle/working/submission.csv', index=False)\n",
    "sample_submission_df.head()"
   ],
   "metadata": {
    "id": "OZuB6CdUmnjf",
    "execution": {
     "iopub.status.busy": "2024-02-19T07:13:18.177287Z",
     "iopub.status.idle": "2024-02-19T07:13:18.177606Z",
     "shell.execute_reply.started": "2024-02-19T07:13:18.177455Z",
     "shell.execute_reply": "2024-02-19T07:13:18.177470Z"
    },
    "trusted": true,
    "ExecuteTime": {
     "start_time": "2024-02-19T07:14:13.123010Z"
    }
   },
   "execution_count": null,
   "outputs": []
  }
 ]
}
